#include "task.h"
#include "hal.h"
#include <string.h>
#include "platform.h"

// #define MAX_THREADS 128

// 全局变量
// kthread_t* threads[MAX_THREADS]; // 线程表
thread init_thread; //第一个线程:init



uint64_t init_stack[256];
thread* current_th=&init_thread;


void init_kthread(){
    io_printf("[init]HELLO!!!");
    schedule();
    while(1) asm("hlt");
}

// void set_stack(task_stack* s, uint64_t ret_addr){
//     s.regs.r15=0;
//     s.regs.r14=0;
//     s.regs.r13=0;
//     s.regs.r12=0;
//     s.regs.rbx=0;
//     s.regs.rbp=0;
//     s.regs.rsi=0;
//     s.regs.rcx=0;
//     s.regs.rax=0;
//     s.regs.ret_addr=ret_addr;
//     return;
// }

// 初始化线程管理
void init_threads() {
    init_thread=(thread){   
        .pid=1,
        .name="init",
        .last=NULL,
        .next=NULL
    };
    //伪造init的栈
    init_stack[255]=(uint64_t)&init_kthread;
    init_stack[254]=0;
    init_stack[253]=0;
    init_stack[252]=0;
    init_stack[251]=0;
    init_stack[250]=0;
    init_stack[249]=0;
    // init_stack.regs.r15=0;
    // init_stack.regs.r14=0;
    // init_stack.regs.r13=0;
    // init_stack.regs.r12=0;
    // init_stack.regs.rbx=0;
    // init_stack.regs.rbp=0;
    // init_stack.regs.rsi=0;
    // init_stack.regs.rcx=0;
    // init_stack.regs.rax=0;
    // init_stack.regs.ret_addr=init_kthread;
}

int do_fork(char* name, void* enter, void* arg, thread* th, uint64_t stack_base){
    // if (next_pid >= MAX_THREADS) {
    //     io_printf("too many threads");
    //     return -1; // 超出最大线程数
    // }
    // 初始化线程控制块
    th->pid = (current_th->pid)++;
    th->name=name;
    th->arg = arg;
    // io_printf("999");
    // 分配栈空间
    th->stack_size = STACK_SIZE;
    th->stack_base = stack_base;
    // thread->stack_base = (uint64_t)kmalloc(thread->stack_size);
    // if (!thread->stack_base) {
    //     kfree(thread);
    //     io_printf("stack");
    //     return -1; // 栈分配失败
    // }

    // 设置栈指针和指令指针
    th->rsp = th->stack_base + th->stack_size - 8;
    th->rip = (uint64_t)enter;
    th->rflags = 0x202; // 默认标志寄存器值
    th->rbp = th->rsp;
    th->cr3 = read_cr3(); // 获取当前页表基址

    // 将线程加入线程链表
    th->last=current_th;
    current_th->next=th;
    th->next=NULL;

    return th->pid;
}

// 创建线程
// int kthread(char* name, void* enter, void* arg) {
//     if (next_pid >= MAX_THREADS) {
//         io_printf("too many threads");
//         return -1; // 超出最大线程数
//     }
//     // io_printf("wan la!!!");
//     // 分配线程控制块
//     kthread_t* thread = (kthread_t*)kmalloc(sizeof(kthread_t));
//     if (thread==NULL) {
//         io_printf("mem");
//         return -1; // 内存分配失败
//     }
//     // io_printf("emm");
//     // 初始化线程控制块
//     thread->pid = next_pid++;
//     strncpy(thread->name, name, sizeof(thread->name) - 1);
//     thread->name[sizeof(thread->name) - 1] = '\0';
//     thread->arg = arg;
//     // io_printf("999");
//     // 分配栈空间
//     thread->stack_size = STACK_SIZE;
//     thread->stack_base = (uint64_t)kmalloc(thread->stack_size);
//     if (!thread->stack_base) {
//         kfree(thread);
//         io_printf("stack");
//         return -1; // 栈分配失败
//     }

//     // 设置栈指针和指令指针
//     thread->rsp = thread->stack_base + thread->stack_size - 8;
//     thread->rip = (uint64_t)enter;
//     thread->rflags = 0x202; // 默认标志寄存器值
//     thread->rbp = thread->rsp;
//     thread->cr3 = read_cr3(); // 获取当前页表基址

//     // 将线程加入线程表
//     threads[thread->pid] = thread;

//     return thread->pid;
// }

// 线程退出
void thread_exit() {
    int pid = current_th->pid; // 获取当前线程的PID
    // kfree((void*)threads[pid]->stack_base);
    // kfree(threads[pid]);
    current_th->last->next = NULL;

    schedule(); // 切换到下一个线程
}

// 调度器
void schedule() {
    // 循环查找可用线程

    thread* th=current_th;
    thread* old_th=current_th;
    do {
        if (th != NULL || th->next== NULL) {
            break;
        }
        th=th->next;
    } while (1);

    // 无可用线程时调度当前线程
    if (th == NULL) {
        // panic("No runnable threads!");
        // io_printf("No runnable threads!");
        return;
    }
    current_th=th;
    // 切换上下文
    switch_context(&(old_th->rsp), th->rsp);
    return;
}

